package com.sunwayhorizo.health.business.registries.place;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.registries.BedDTO;
import com.sunwayhorizo.health.business.registries.organization.query.DepartmentQueryLocal;
import com.sunwayhorizo.health.business.registries.place.query.BedQueryLocal;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.AD;
import com.sunwayhorizo.health.hl7.datatypes.BAG_EN;
import com.sunwayhorizo.health.hl7.datatypes.CE;
import com.sunwayhorizo.health.hl7.datatypes.CS;
import com.sunwayhorizo.health.hl7.datatypes.SET_II;
import com.sunwayhorizo.health.hl7.datatypes.common.ADXPImpl;
import com.sunwayhorizo.health.hl7.datatypes.common.CSImpl;
import com.sunwayhorizo.health.hl7.datatypes.common.ENImpl;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Hl7Entity;
import com.sunwayhorizo.health.hl7.rim.Place;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.EntityAddrUse;
import com.sunwayhorizo.health.hl7.vocabulary.EntityCode;
import com.sunwayhorizo.health.hl7.vocabulary.EntityDeterminer;
import com.sunwayhorizo.health.hl7.vocabulary.EntityNameUse;
import com.sunwayhorizo.health.hl7.vocabulary.EntityStatus;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;
import com.sunwayhorizo.health.hl7.vocabulary.RoleClass;

@Stateless
@Name("BedManager")
public class BedManager extends BaseManager implements BedManagerLocal
{

    private BedQueryLocal bedQuery = (BedQueryLocal) Component.getInstance("BedQuery");


    public ResultsDTO newBed(BedDTO bedDTO) throws Hl7Exception
    {
        Role role = createBed(bedDTO);
        return getResultsDTO("新增床位成功", true, role.getRoleId().toString());
    }


    @SuppressWarnings({ "rawtypes" })
    public ResultsDTO delBed(List ids) throws Hl7Exception
    {
        if (ListUtil.isEmpty(ids))
            return this.getResultsDTO("删除床位信息失败", false, null);
        for (int i = 0; i < ids.size(); i++)
        {
            String id = (String) ids.get(i);
            Role role = baseQuery.findRoleById(Long.valueOf(id));
            if (null != role)
            {
                if (role.getPlayerEntity().getStatusCode().equals(EntityStatus.EMPTYBED))
                {
                    em.remove(role.getPlayerEntity());
                    em.remove(role);
                    log.info("BedManager-delBed：删除床位成功");
                    return this.getResultsDTO("成功删除床位信息", true, id);
                }
                else
                {
                    log.info("BedManager-delBed：该床位在占用，不能删除");
                    return this.getResultsDTO("该床位在占用，不能删除", true, id);
                }
            }

        }
        return this.getResultsDTO("成功删除床位信息", true, null);
    }


    public ResultsDTO updateBed(BedDTO bedDTO) throws Hl7Exception
    {
        if (null == bedDTO || StrUtil.isEmpty(bedDTO.getRimBedRoleId()))
            return this.getResultsDTO("床号为空，不能修改", true, null);
        Role role = baseQuery.findRoleById(Long.valueOf(bedDTO.getRimBedRoleId()));
        
        if (null == role)
            return this.getResultsDTO("床位为空，不能修改", true, null);
        
        Place place = (Place) role.getPlayerEntities();
        if (null != place)
        {
            convertPlaceToBedDTO(bedDTO, place);
            em.merge(place);
            return this.getResultsDTO("修改床位成功", true, null);
        }
        else
        {
            return this.getResultsDTO("修改床位失败", true, null);
        }
    }


    public ResultsDTO findBedListByWorkGroupId(String workGroupId) throws Hl7Exception
    {
        if (StrUtil.isEmpty(workGroupId))
            return getResultsDTO("病区id为空，不能查询到床位", true, null);
        List<Role> list = bedQuery.findBedListByWorkgroupId(workGroupId, null);
        List<BedDTO> returnList = converBedDTOListToRoleList(list);
        return this.getResultsDTO("成功得到床位列表", true, returnList);
    }


    @Override
    public ResultsDTO findBedListByWorkGroupId(String workGroupId, String status) throws Hl7Exception
    {
        if (StrUtil.isEmpty(workGroupId))
            return getResultsDTO("病区id为空，不能查询到床位", true, null);
        List<Role> list = bedQuery.findBedListByWorkgroupId(workGroupId, status);
        List<BedDTO> returnList = converBedDTOListToRoleList(list);
        return this.getResultsDTO("成功得到床位列表", true, returnList);
    }


    public ResultsDTO findBedListByDept(String deptId, String status) throws Hl7Exception
    {
        if (StrUtil.isEmpty(deptId))
            return this.getResultsDTO("科室id为空，不能查询到该科室下的床位", true, null);
        DepartmentQueryLocal departManager = (DepartmentQueryLocal) Component.getInstance("DepartmentQuery");
        List<Object> workGroupIds = departManager.findWoroGroupIdsByDeptId(deptId);
        List<Role> list = bedQuery.findBedRoleByWGListOrStatus(workGroupIds, status);
        List<BedDTO> returnList = converBedDTOListToRoleList(list);
        return this.getResultsDTO("成功得到床位列表", true, returnList);
    }


    public ResultsDTO findBedListByWardId(String roomId) throws Hl7Exception
    {
        List<Place> list = bedQuery.findBedListByWardId(roomId);
        List<BedDTO> returnList = new ArrayList<BedDTO>();
        if (ListUtil.isNotEmpty(list))
        {
            for (Place place : list)
            {
                BedDTO bedDTO = new BedDTO();
                bedDTO.setBedId(place.getEntityId().toString());
                getBedNo(place, bedDTO);
                bedDTO.setType(getDictionaryFactory().getDictionaryDTOByCe(place.getPlTypeCode()));
                bedDTO.setType(getDictionaryFactory().getDictionaryDTOByCe(place.getPlLevelCode()));
                returnList.add(bedDTO);
            }
        }
        ResultsDTO resultsDTO = getResultsDTO("查询成功", true, returnList);
        return resultsDTO;
    }


    public ResultsDTO validateBedName(String workGroupId, String bedNo) throws Hl7Exception
    {
        List<Long> list = bedQuery.findBedRoleIdListByWGOrBedNo(workGroupId, bedNo);
        if (ListUtil.isNotEmpty(list))
        {
            return this.getResultsDTO("该床位已经存在", true, "1");
        }
        else
        {
            return this.getResultsDTO("该床位不存在", true, "0");
        }

    }

    @Override
    public Role createBed(BedDTO bedDTO) throws Hl7Exception
    {
        // 准备基础数据
        Hl7Entity workGroupEntity = null;
        if (StrUtil.isNotEmpty(bedDTO.getWorkGroupRoleId()))
        {
            workGroupEntity = baseQuery.findHl7EntityById(Long.valueOf(bedDTO.getWorkGroupRoleId()));
        }
        // 创建一个床位实体
        Place bedPlace = createPlace();

        // 给place进行赋值
        bedPlace = convertPlaceToBedDTO(bedDTO, bedPlace);

        if (null != bedPlace && null != workGroupEntity)
        {
            String extenID = em.createNativeQuery("select EXTEN_CODE.NEXTVAL from dual").getResultList().get(0).toString();
            SET_II oraId = getDataTypeFactory().newSET_II(root, "org" + extenID, "true");
           
            Role role = getRoleFactory().newRole(RoleClass.IDENT, DataTypeUtil.getCE(EntityCode.BED.toString()), bedPlace, workGroupEntity,
                oraId);
            
            ControlAct controlAct = newControlAct(ActCode.BED, ParticipationType.SBJ, extenID, role);

            em.persist(controlAct);

            log.info("BedManager-createBed:新增床位成功,床位id为：" + bedPlace.getEntityId().toString());
            return role;
        }
        else
        {
            log.info("BedManager-createBed:新增床位失败，原因：" + "科室或床位为空！");
            return null;
        }
    }
    
    @Override
    public void modifyBedStatus(Role bedRole, CS status) throws Hl7Exception
    {
        if(null == bedRole) { log.info(" 床位角色为空");   return;}
        Place place = (Place)bedRole.getPlayerEntity();
        place.setStatusCode(status);
        update(place);
        log.info(" 修改床位状态成功");
        
    }

    private Place createPlace() throws Hl7Exception
    {
        String extenID = em.createNativeQuery("select EXTEN_CODE.NEXTVAL from dual").getResultList().get(0).toString();
        SET_II placeId = getDataTypeFactory().newSET_II(root, "PLC" + extenID, "true");
        CE ce = getDataTypeFactory().newCE(EntityCode.BED.toString());
        Place bedPlace = getEntityFactory().newPlace(ce, EntityDeterminer.INSTANCE, placeId);
        return bedPlace;
    }


    private Place convertPlaceToBedDTO(BedDTO bedDTO, Place bedPlace) throws Hl7Exception
    {

        // 设置Bed名称
        String[] placeName = new String[1];
        if (StrUtil.isNotEmpty(bedDTO.getBedNo()))
        {
            placeName[0] = bedDTO.getBedNo();
            String placeType[] = { null };
            String placeNameUseCode = EntityNameUse.L.code().toString();
            BAG_EN bagEnName = DataTypeUtil.getBagEN(placeName, placeType, placeNameUseCode);
            bedPlace.setName(bagEnName);
        }

        // 房间号
        if (StrUtil.isNotEmpty(bedDTO.getWardId()))
        {
            String[] addr = new String[1];
            if (StrUtil.isNotEmpty(bedDTO.getWardId()))
            {
                addr[0] = bedDTO.getWardId();
            }
            String[] addrPart = { EntityAddrUse.H.code().toString() };
            AD roomId = DataTypeUtil.getAD(addr, addrPart, EntityAddrUse.H.code().toString());
            bedPlace.setAddr(roomId);
        }

        // 床位状态
        bedPlace.setStatusCode(DataTypeUtil.getCS(bedDTO.getStatus()));

        // 床位类型
        if (StrUtil.isNotEmpty(bedDTO.getSex()))
        {
            bedPlace.setDeterminerCode(DataTypeUtil.getCS(bedDTO.getSex()));
        }

        // 等级
        if (bedDTO.getLevel() != null && StrUtil.isNotEmpty(bedDTO.getLevel().getConceptCode()))
        {
            CE placeCE = getDictionaryFactory().getCeByDictionaryDTO(bedDTO.getLevel());
            bedPlace.setPlLevelCode(placeCE);
        }
        // 类型
        if (bedDTO.getType() != null && StrUtil.isNotBlank(bedDTO.getType().getConceptCode()))
        {
            CE placeTypeCE = getDictionaryFactory().getCeByDictionaryDTO(bedDTO.getType());
            bedPlace.setPlTypeCode(placeTypeCE);
        }
        return bedPlace;
    }

    //组装床位DTO集合
    private List<BedDTO> converBedDTOListToRoleList(List<Role> list) throws Hl7Exception
    {
        if (ListUtil.isEmpty(list)) return null;
        List<BedDTO> returnList = new ArrayList<BedDTO>();
        if (ListUtil.isNotEmpty(list))
        {
            for (Role role : list)
            {
                Place place = (Place) role.getPlayerEntities();
                BedDTO bedDTO = new BedDTO();
                //床位RIM entityId
                bedDTO.setBedId(place.getEntityId().toString());
                //床位状态
                bedDTO.setStatus(place.getStatusCode().code().toString());
                //床位类型
                bedDTO.setSex(role.getPlayerEntity().getDeterminerCode().code().toString());
                //编制类型 
                bedDTO.setType(getDictionaryFactory().getDictionaryDTOByCe(place.getPlTypeCode()));
                //床位等级
                bedDTO.setLevel(getDictionaryFactory().getDictionaryDTOByCe(place.getPlLevelCode()));
                //房间号
                getRoomId(place, bedDTO);
                //床号
                getBedNo(place, bedDTO);
                //床位角色 RIM 角色Id
                bedDTO.setRimBedRoleId(role.getRoleId().toString());
                // 工作组RIM 实体id
                bedDTO.setWorkGroupRoleId(String.valueOf(role.getScoperEntities().getEntityId())); 
                returnList.add(bedDTO);
            }
        }
        return returnList;
    }

    @SuppressWarnings("rawtypes")
    private void getRoomId(Place place, BedDTO bedDTO) throws Hl7Exception
    {
        AD addrs = place.getAddr();
        if(null != addrs)
        {
            List mList = addrs.toList();
            for (int i = 0; i < mList.size(); i++)
            {
                ADXPImpl ad = (ADXPImpl) mList.get(i);
                String type = ad.partType().code().toString();
                if(type.equals(EntityAddrUse.H.code().toString()))
                {
                    bedDTO.setWardId(ad.literal().toString());
                }
            }
        }
    }


    @SuppressWarnings("rawtypes")
    private void getBedNo(Place place, BedDTO bedDTO) throws Hl7Exception
    {
        BAG_EN names = place.getName();
        if(names != null)
        {
            List mList = names.toList();
            for(int i=0; i<mList.size(); i++)
            {
                ENImpl en = (ENImpl) mList.get(i);
                Set set = (Set) en.use().toSet();
                String code = "";
                if(!set.isEmpty())
                {
                    CSImpl use = (CSImpl) set.iterator().next();
                    code = use.code().toString();
                }
                if(code.equals(EntityNameUse.L.code().toString()))
                {
                    bedDTO.setBedNo(en.formatted().toString());
                }
            }
        }
    }

}
